/**************************************************************************************

                                        _ooOoo_                                                           
                                       o8888888o                                                          
                                       88" . "88                                                          
                                       (| -_- |)                                                          
                                       O\  =  /O                                                          
                                    ____/`---'\____                                                       
                                  .'  \\|     |\\  `.                                                     
                                 /  \\|||  :  |||//  \                                                    
                                /  _||||| -:- |||||-  \                                                   
                                |   | \\\  -  /// |   |                                                   
                                | \_|  ''\---/''  |   |                                                   
                                \  .-\__  `-`  ___/-. /                                                   
                              ___`. .'  /--.--\  `. . __                                                  
                           ."" '<  `.___\_<|>_/___.'  >'"".                                               
                           | | :  `- \`.;`\ _ /`;.`/ - ` : | |                                            
                          \  \ `-.   \_ __\ /__ _/   .-` /  /                                             
                     ======`-.____`-.___\_____/___.-`____.-'======                                        
                                        `=---='                                                           
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                         
                                佛祖保佑        永无BUG                                                    

**---------------------------------File Info-------------------------------------------
**                                                                                                        
** @file:               cmos_capture_data_lx.v
** @author:             LeXin567567
** @date:               2024-06-26
** @brief:              
** @problems: 1. 为什么都要是延时一个时钟周期的？  没搞懂里面延时的玩法            
**                                                                                                        
**-------------------------------------------------------------------------------------
**************************************************************************************/


module cmos_capture_data_lx (
    input rst_n,
    input cam_pclk,
    input cam_vsync,
    input cam_href,
    input [7:0] cam_data,

    output cmos_frame_vsync,
    output cmos_frame_href,
    output cmos_frame_valid,
    output [15:0] cmos_frame_data     
);


parameter WAIT_FRAME = 4'd10;

reg cam_vsync_d0;
reg cam_vsync_d1;
reg cam_href_d0;
reg cam_href_d1;
reg [3:0] cmos_ps_cnt;
reg frame_val_flag; // 帧有效标志


reg [7:0] cam_data_d0;
reg [15:0] cmos_data_t;
reg byte_flag;
reg byte_flag_d0;

wire pos_vsync;

// 采输入场同步信号的上升沿
assign pos_vsync = (~cam_vsync_d1) & cam_vsync_d0;

// 输出帧有效信号
assign cmos_frame_vsync = frame_val_flag ? cam_vsync_d1 : 1'b0;
// 输出行有效信号
assign cmos_frame_href = frame_val_flag ? cam_href_d1 : 1'b0;
// 输出数据使能有效信号
assign cmos_frame_valid = frame_val_flag ? byte_flag_d0 : 1'b0;
// 输出数据
assign cmos_frame_data = frame_val_flag ? cmos_data_t : 1'b0; 


// 采集输入场同步信号的上升沿
always @(posedge cam_pclk or negedge rst_n) begin
    if(!rst_n)
    begin
        cam_vsync_d0 <= 1'b0;
        cam_vsync_d1 <= 1'b0;
        cam_href_d0 <= 1'b0;
        cam_href_d1 <= 1'b0;
    end
    else
    begin
        cam_vsync_d0 <= cam_vsync;
        cam_vsync_d1 <= cam_vsync_d0;
        cam_href_d0 <= cam_href;
        cam_href_d1 <= cam_href_d0;
    end
end

// 对帧数进行计数
always @(posedge cam_pclk or negedge rst_n) begin
    if(!rst_n)
        cmos_ps_cnt <= 4'd0;
    else if (pos_vsync && (cmos_ps_cnt < WAIT_FRAME))
        cmos_ps_cnt <= cmos_ps_cnt + 4'd1;
end


// 帧有效标志
always @(posedge cam_pclk or negedge rst_n) begin
    if(!rst_n)
        frame_val_flag <= 1'b0;
    else if( (cmos_ps_cnt == WAIT_FRAME) && pos_vsync)
        frame_val_flag <= 1'b1;
    else
        frame_val_flag <= frame_val_flag;
end



// 8位转16位
always @(posedge cam_pclk or negedge rst_n) begin
    if(!rst_n)
    begin
        cmos_data_t <= 16'd0;
        cam_data_d0 <= 8'd0;
        byte_flag <= 1'b0;
    end
    else if( cam_href )
    begin
        byte_flag <= ~byte_flag;
        cam_data_d0 <= cam_data;
        if(byte_flag)
            cmos_data_t <= {cam_data_d0, cam_data};
        else
            cmos_data_t <= cmos_data_t;
    end
    else
    begin
        byte_flag <= 1'b0;
        cam_data_d0 <= 8'b0;
    end
end


// 产生输出数据有效信号(cmos_frame_valid)
always @(posedge cam_pclk or negedge rst_n) begin
    if(!rst_n)
        byte_flag_d0 <= 1'b0;
    else
        byte_flag_d0 <= byte_flag;
end


endmodule